package com.liuwei.assemble.common;

import com.baomidou.mybatisplus.generator.config.ConstVal;

import org.apache.commons.io.FileUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Properties;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by lykosliu on 2017/1/22.
 */
public class GIOUtils {
    private static final Logger logger = LoggerFactory.getLogger(GIOUtils.class);
    private static final int BUFFER = 8192;
    public static File checkOrCreateDir(String path){
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        return file;
    }
    public static void vmToFile(VelocityContext context, String templatePath, String outputFile) throws IOException {
        Properties p = new Properties();
        p.setProperty(ConstVal.VM_LOAD_PATH_KEY, ConstVal.VM_LOAD_PATH_VALUE);
        p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
        p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
        p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
        //p.setProperty(Velocity.OUTPUT_ENCODING, ConstVal.UTF8);
        p.setProperty("file.resource.loader.unicode", "true");
        VelocityEngine velocity = new VelocityEngine(p);
        Template template = velocity.getTemplate(templatePath, ConstVal.UTF8);
        FileOutputStream fos = new FileOutputStream(outputFile);
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, ConstVal.UTF8));
        template.merge(context, writer);
        writer.close();
    }


    /**
     * 执行压缩操作
     */
    public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName) {
        boolean flag = false;
        File file = new File(sourceFilePath);
        if (!file.exists()){
            throw new RuntimeException(sourceFilePath + "不存在！");
        }
        try {
            File baseZipPath = new File(zipFilePath);
            if(!baseZipPath.exists()){
                baseZipPath.mkdirs();
            }
            File zipFile = new File(zipFilePath + "/" + fileName +".zip");
            if(!zipFile.exists()){
                zipFile.createNewFile();
            }
            FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
            CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,new CRC32());
            ZipOutputStream out = new ZipOutputStream(cos);
            String basedir = "";
            compressByType(file, out, basedir);
            out.close();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return flag;
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     * @throws IOException 
     */
    public static boolean deleteDir(File dir) throws IOException {
        if (dir.isDirectory()) {
        	FileUtils.cleanDirectory(dir);
            /*String[] children = dir.list();
            //递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }*/
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }

    /**
     * 判断是目录还是文件，根据类型（文件/文件夹）执行不同的压缩方法
     * @param file
     * @param out
     * @param basedir
     */
    public static void compressByType(File file, ZipOutputStream out, String basedir) {
        /* 判断是目录还是文件 */
        if (file.isDirectory()) {
            compressDirectory(file, out, basedir);
        } else {
            compressFile(file, out, basedir);
        }
    }

    /**
     * 压缩一个目录
     * @param dir
     * @param out
     * @param basedir
     */
    public static void compressDirectory(File dir, ZipOutputStream out, String basedir) {
        if (!dir.exists()){
            return;
        }

        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            /* 递归 */
            compressByType(files[i], out, basedir + dir.getName() + "/");
        }
    }

    /**
     * 压缩一个文件
     * @param file
     * @param out
     * @param basedir
     */
    public static void compressFile(File file, ZipOutputStream out, String basedir) {
        if (!file.exists()) {
            return;
        }
        try {
//        	String[] arr = basedir.split("/");
//        	String dirStr = "src/";
//        	if(arr[0].contains("src")){
//        		for(int i = 1;i < arr.length; i++){
//        			dirStr  +=arr[i] + "/";
//        		}
//        	}
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            ZipEntry entry = new ZipEntry(basedir + file.getName());
            out.putNextEntry(entry);
            int count;
            byte data[] = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
            bis.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public static void copyFolder(File srcFile,File destFile) {
		try {
			destFile.mkdirs();
			FileUtils.copyDirectory(srcFile, destFile);
		} catch (Exception e) {
			logger.error("复制整个文件夹内容操作出错{}", e);
			System.out.println("复制整个文件夹内容操作出错");
			e.printStackTrace();
		}
    }


    /**
     * 复制整个文件夹内容
     * @param oldPath String 原文件路径 如：c:/fqf
     * @param newPath String 复制后路径 如：f:/fqf/ff
     * @return boolean
     */
    public static void copyFolder(String oldPath, String newPath) {
    	File srcFile = new File(oldPath);
    	File destFile = new File(newPath);
    	copyFolder(srcFile,destFile);
//        try {
//            (new File(newPath)).mkdirs(); //如果文件夹不存在 则建立新文件夹
//            File a=new File(oldPath);
//            String[] file=a.list();
//            File temp=null;
//            logger.error("oldPath:{}",oldPath);
//            for (int i = 0; i < file.length; i++) {
//                if(oldPath.endsWith(File.separator)){
//                    temp=new File(oldPath+file[i]);
//                }
//                else{
//                    temp=new File(oldPath+File.separator+file[i]);
//                }
//
//                if(temp.isFile()){
//                    FileInputStream input = new FileInputStream(temp);
//                    FileOutputStream output = new FileOutputStream(newPath + "/" +
//                            (temp.getName()).toString());
//                    byte[] b = new byte[1024 * 5];
//                    int len;
//                    while ( (len = input.read(b)) != -1) {
//                        output.write(b, 0, len);
//                    }
//                    output.flush();
//                    output.close();
//                    input.close();
//                }
//                if(temp.isDirectory()){//如果是子文件夹
//                    copyFolder(oldPath+"/"+file[i],newPath+"/"+file[i]);
//                }
//            }
//        }
//        catch (Exception e) {
//            logger.error("复制整个文件夹内容操作出错{}",e);
//            System.out.println("复制整个文件夹内容操作出错");
//            e.printStackTrace();
//
//        }

    }


    public static void responseJson(HttpServletResponse response, String responseCode, String message, String zipName) throws IOException{
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.write("{\"rspCode\":\"" + responseCode + "\",\"\":\"" + message + "\",\"zipName\":\"" + zipName + "\"}");
        out.flush();
    }
}
